package com.app.core.mybatis;

import cn.hutool.core.util.StrUtil;
import com.app.core.mvc.result.Code;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.lang.reflect.Field;

/**
 * @author qiangt
 */
@Slf4j
@Data
public class BasePageDto implements Serializable {
    @ApiModelProperty(name = "orderField", value = "排序列，entity属性", dataType = "String", position = 97)
    private String orderField;

    @ApiModelProperty(name = "pageCurrent", value = "当前页数", dataType = "Integer", example = "1", position = 98)
    private Long pageCurrent = 1L;

    @ApiModelProperty(name = "pageSize", value = "每页几条", dataType = "Integer", example = "20", position = 99)
    private Long pageSize = 10L;

    @ApiModelProperty(name = "isAsc", value = "是否升序", dataType = "boolean", position = 97)
    private Boolean isAsc = true;

    @ApiModelProperty(name = "orderSql", value = "排序列，数据列", hidden = true)
    private String orderSql;

    public void resolveOrderSql(Class<?> clazz) {
        if (StrUtil.isBlank(this.orderField)) {
            return;
        }
        String column = this.getOrderColumn(clazz, this.orderField);
        this.orderSql = StrUtil.isBlank(column) ? null : " order by " + column + (isAsc ? " asc" : " desc");
    }

    /**
     * 获取排序字段对应的数据库列名，防止sql注入
     *
     * @param clazz
     * @param orderByField
     * @return
     */
    private String getOrderColumn(Class<?> clazz, String orderByField) {
        Field field = null;
        boolean orderInField = false;
        try {
            field = clazz.getDeclaredField(orderByField);
        } catch (NoSuchFieldException e) {
            try {
                field = clazz.getSuperclass().getDeclaredField(orderByField);
            } catch (NoSuchFieldException ex) {
                throw Code.A00032.toCodeExceptionWithArgs(clazz.getSimpleName(), orderByField);
            }
        }
        String columnName = StrUtil.toUnderlineCase(field.getName());
        boolean isTableField = field.isAnnotationPresent(TableField.class);
        if (isTableField) {
            TableField tableField = field.getAnnotation(TableField.class);
            columnName = StrUtil.isNotBlank(tableField.value()) ? tableField.value() : columnName;
        }
        return columnName;
    }
}
